package es.aa.android.cartomatic.implementations.da;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;
import android.graphics.BitmapFactory;

import java.util.ArrayList;
import java.util.List;

import es.aa.android.cartomatic.domain.Card;
import es.aa.android.cartomatic.domain.Deck;
import es.aa.android.cartomatic.exceptions.DataAccessException;
import es.aa.android.cartomatic.interfaces.da.ISQLiteAccess;

public class SQLiteAccess implements ISQLiteAccess {

    private SQLite mDB;
    private SQLiteDatabase db;

    private void accesDB(Context context) {
        if (mDB == null) {
            mDB = new SQLite(context, null, SQLiteConstants.VERSION);
        }
        db = mDB.getWritableDatabase();
    }

    private void closeDB() {
        db.close();
    }

    public void writeDeck(Context context, Deck deck) {

        accesDB(context);

        SQLiteStatement statement = db.compileStatement(SQLiteConstants.INSERT_DECK);
        statement.clearBindings();
        statement.bindString(1, String.valueOf(deck.getId()));
        statement.bindString(2, deck.getName());
        statement.bindString(3, deck.getDescription());
        statement.bindBlob(4, deck.getImageArray());
        statement.execute();

        closeDB();
    }

    
    
    public void writeCardOnDeck(Context context, int idDeck, ArrayList<Integer> idCard) {
    	
		for (int i = 0; i < idCard.size(); i++) {
			
	        accesDB(context);
	        String[] test = new String[1];
	        test[0] = String.valueOf(idDeck);
	        Cursor cursor = db.rawQuery(SQLiteConstants.SELECT_CARDS_ON_DECK, test);
	        
	        if(cursor.moveToNext()){
	        	
	        	String[] values = new String[2];
	        	values[0] = String.valueOf(idDeck);
	        	values[1] = String.valueOf(idCard.get(i));
	            Cursor updateNum = db.rawQuery(SQLiteConstants.UPDATE_SUM_NUM_OF_CARDS, values);
	            
	            while (updateNum.moveToNext()){}
	            
	        }else{
	        	
				SQLiteStatement statement = db.compileStatement(SQLiteConstants.INSERT_CARD_BELONG);
				statement.clearBindings();
				statement.bindDouble(1, idDeck);
				statement.bindDouble(2, idCard.get(i));
				statement.bindDouble(3, 1);
				statement.execute();		
				
	        }
	       	        
	        closeDB();
	        
		}
		
    }


    public Deck readDeck(Context context, int idDeck) {

        Deck deck = new Deck();
        List<Card> cards = new ArrayList<Card>();
        accesDB(context);
        String[] test = new String[1];
        test[0] = String.valueOf(idDeck);
        
        Cursor cursor = db.rawQuery(SQLiteConstants.SELECT_CARDS_ID_OF_DECK, test);
        	
        while (cursor.moveToNext()) {
            int idCard = cursor.getInt(0);
            Card card = readCard(context, idCard);
            cards.add(card);
        }

        deck.setCards(cards);

        cursor.close();
        closeDB();

        return deck;
    }

    public List<Deck> readDeckLibrary(Context context) {
        accesDB(context);
        List<Deck> decks = new ArrayList<Deck>();
        Cursor cursor = db.rawQuery(SQLiteConstants.SELECT_ALL_DECKS, null);

        while (cursor.moveToNext()) {
            Deck deck = new Deck();
            int id = cursor.getInt(0);
            String title = cursor.getString(1);
            String description = cursor.getString(2);
            byte[] imageArray = cursor.getBlob(3);

            deck.setId(id);
            deck.setName(title);
            deck.setDescription(description);
            deck.setImage(BitmapFactory.decodeByteArray(imageArray, 0, imageArray.length));
            // ALOMEJOR LEERLO CON TODAS LAS CARTAS
            decks.add(deck);
        }

        cursor.close();
        closeDB();
        return decks;
    }
    
    public List<Deck> readDecksForOptions(Context context) {
        accesDB(context);
        List<Deck> decks = new ArrayList<Deck>();
        Cursor cursor = db.rawQuery(SQLiteConstants.SELECT_DECKS_FOR_OPTIONS, null);

        while (cursor.moveToNext()) {
            Deck deck = new Deck();
            int id = cursor.getInt(0);
            String title = cursor.getString(1);

            deck.setId(id);
            deck.setName(title);
            decks.add(deck);
        }

        cursor.close();
        closeDB();
        return decks;
    }
    public void writeCard(Context context, Card card) {

        accesDB(context);
        SQLiteStatement statement = db.compileStatement(SQLiteConstants.INSERT_CARD);
        statement.clearBindings();
        statement.bindString(1, String.valueOf(card.getId()));
        statement.bindString(2, card.getName());
        statement.bindString(3, card.getDescription());
        statement.bindBlob(4, card.getImageArray());
        statement.executeInsert();

        closeDB();
    }

    public Card readCard(Context context, int idCard) {

        accesDB(context);
        Card card = new Card();
        Cursor cursor = db.rawQuery(SQLiteConstants.SELECT_CARD + idCard, null);

        if (cursor.moveToNext()) {
            int id = cursor.getInt(0);
            String title = cursor.getString(1);
            byte[] image = cursor.getBlob(2);
            String description = cursor.getString(3);
            card.setId(id);
            card.setName(title);
            card.setImage(BitmapFactory.decodeByteArray(image, 0, image.length));
            card.setDescription(description);
        }

        cursor.close();
        closeDB();
        return card;
    }

    public List<Card> readCardLibrary(Context context) {
        accesDB(context);
        List<Card> cards = new ArrayList<Card>();
        Cursor cursor = db.rawQuery(SQLiteConstants.SELECT_ALL_CARDS, null);

        while (cursor.moveToNext()) {
            Card card = new Card();

            int id = cursor.getInt(0);
            String title = cursor.getString(1);
            byte[] image = cursor.getBlob(3);
            String description = cursor.getString(2);
            card.setId(id);
            card.setName(title);
            card.setImage(BitmapFactory.decodeByteArray(image, 0, image.length));
            card.setDescription(description);

            cards.add(card);
        }

        cursor.close();
        closeDB();
        return cards;
    }
    
    public void deleteCardOnDeck(Context context, int idDeck, ArrayList<Integer> idCard) {
    	
		for (int i = 0; i < idCard.size(); i++) {
			
			accesDB(context);
	        String[] test = new String[1];
	        test[0] = String.valueOf(idDeck);
	        Cursor cursor = db.rawQuery(SQLiteConstants.SELECT_CARDS_ON_DECK, test);
	        
	        if(cursor.moveToNext() ){
	        	
	        	int num = cursor.getInt(0);
	        	if(num>1){
	        		
		        	String[] valuesUPD = new String[2];
		        	valuesUPD[0] = String.valueOf(idDeck);
		        	valuesUPD[1] = String.valueOf(idCard.get(i));
		            Cursor updateNum = db.rawQuery(SQLiteConstants.UPDATE_SUBTRACT_NUM_OF_CARDS, valuesUPD);
		            
		            while (updateNum.moveToNext()){}
		            
	        	}else{
	        		
	        		String[] valuesDel = new String[2];
	        		valuesDel[0] = String.valueOf(idDeck);
	        		valuesDel[1] = String.valueOf(idCard.get(i));
	    	        Cursor statement = db.rawQuery(SQLiteConstants.DELETE_CARD_IS_OF_DECK, valuesDel);

	    	        while (statement.moveToNext()){}
	    	        
	        	}
	        	
	        }
	        
	        closeDB();
	        
		}
    }


}
